\chapter{Instrumentation dynamique de code}
Ici l'objectif est de collecter des informations lors de l'exécution du binaire instrumenté. En particulier, nous souhaitons connaître les temps inclusifs et exclusifs des fonctions instrumentées.

\section{Choix d'instrumentation}
Nous avons choisi d'instrumenter toutes les fonctions du code source de façon dynamique. En effet, nous avons besoin de calculer les temps exclusifs, c'est-à-dire de soustraire au temps inclusif tous les temps passés à exécuter d'autres fonctions appelées par la fonction que nous observons. 

Il faut donc instrumenter toutes les fonctions appelées. Le plus simple est de les instrumenter toutes et d'utiliser une variable pour indiquer si la fonction a été instrumentée par l'utilisateur, donc si nous souhaitons retenir et afficher ses résultats, ou si elle a juste été traitée pour des raisons pratiques.

\section{Ajout d'appel de fonction}
Nous souhaitons ajouter un appel à une fonction présente dans une librairie dynamique au début et à la fin de l'exécution d'une fonction instrumentée.

\noindent Pour cela, les étapes sont :
\begin{enumerate}
	\item Construction de la signature de la fonction
	\item Construction des paramètres de la fonction. Ici, ils sont au nombre de deux : le nom de la fonction et de la caractère "required" qui indique si l'utilisateur avait instrumenté cette fonction.
	\item Construction de la déclaration de fonction.
	\item Construction du noeud gimple qui va contenir cet appel de fonction
	\item Insertion du gimple au bout de chaque arc sortant du bloc d'entrée.
\end{enumerate}

\vspace{5mm}
\begin{lstlisting}
	// signature de la fonction
	func_signature = build_function_type_list(void_type_node, ptr_type_node, NULL_TREE);		
	
	// parametre nom de la fonction
	snprintf(msg, 50, fndecl_name(cfun->decl));
	param_name = build_string_literal (50, msg);	
	
	// parametre required
	if (item_in_vector(fndecl_name(cfun->decl), vec_required_dyn))
		snprintf(msg2,4,"oui");		
	else
		snprintf(msg2,4,"non");
	param_req = build_string_literal (4, msg2);	
	// ajout de l'appel a enter_function, au debut de la fonction				
	func = build_fn_decl("enter_function", func_signature);		
	gs=gimple_build_call (func,2,param_name,param_req);
				
	FOR_EACH_EDGE(target,edge_it,ENTRY_BLOCK_PTR->succs)
	{
		gsi = gsi_start_bb(target->dest);
		gsi_insert_before (&gsi, gs, GSI_NEW_STMT);
	}
\end{lstlisting}

Pour l'ajout des appels à exit\_function, le principe est le même, sauf que le gimple créé est inséré au bout de chaque arc précédent le noeud de sortie.

\section{Librairie Runtime}
Nous avons écrit en C++ une bibliothèque qui met à disposition deux fonctions : enter\_function et exit\_function. Pour que ces fonctions soient disponibles de l'extérieur, soient correctement nommées dans la table des symboles, nous utilisons {\tt extern "C"}.

Les fonctions enter\_function et exit\_function récupèrent~: le nom de la fonction passé en paramètre, un entier qui indique si la fonction a été instrumentée par l'utilisateur, le temps grâce à la fonction {\tt gettimeofday}, et ajoutent les temps ainsi calculés à un vecteur.

Nous avons utilisé la fonction {\tt main} comme repère : dans tout programme, elle sera la première à effectuer un appel à enter\_function et la dernière à appeler exit\_function. Cela nous permet d'ouvrir et de fermer le fichier de traces au runtime.

\noindent Ce vecteur est ensuite écrit dans le fichier de traces dynamique sous la forme :
\begin{verbatim}
Call 0 required 1 function main entry 1386185396049509 exit 1386185396054303
Call 1 required 1 function A entry 1386185396049597 exit 1386185396052093
...
\end{verbatim}


